<?php

namespace iflow\Helper\Arr;

class Arr extends Collection {

    /**
     * 通过key 获取 value 支持多层级
     * @param string $name key
     * @param mixed $default 默认值
     * @return mixed
     */
    public function get(string $name = '', mixed $default = []): mixed {
        if ($name === '') return $this->items;
        $keys    = explode('@', $name);

        if (!$this->offsetExists($keys[0])) return $default;

        if (empty($keys[1])) return $this->offsetGet($keys[0]) ?? $default;

        // 按.拆分成数组进行判断
        $names = explode('.', $keys[1]);
        return count($names) <= 1
            ? ($this->items[$keys[0]][$names[0]] ?? $default)
            : $this->getDeepValue($names, $this->offsetGet($keys[0]), $default);
    }

    /**
     * 获取深度值
     * @param mixed $names
     * @param mixed $array
     * @param mixed $default
     * @return array|mixed|null
     */
    protected function getDeepValue(mixed $names, mixed $array = [], mixed $default = []): mixed {
        if (count($names) === 1) {
            $key = array_shift($names);
            return array_key_exists($key, $array) ? $array[$key] : $default;
        }

        $key = array_shift($names);
        if (count($names) >= 1 && !is_array($array[$key])) {
            return $default;
        }
        return array_key_exists($key, $array) ? $this->getDeepValue($names, $array[$key]) : $default;
    }

    public function offsetSet(mixed $offset, mixed $value): mixed {
        $offset = is_string($offset) ? explode('.', $offset) : [ $offset ];
        $pKey = array_shift($offset);

        if (count($offset) > 0) {
            $oldValue = $this->offsetGet($pKey);
            $value = $this->setDeepValue($offset, $oldValue, $value);
        }
        return parent::offsetSet($pKey, $value); // TODO: Change the autogenerated stub
    }

    /**
     * 设置子级值
     * @param mixed $offset
     * @param mixed $oldValue
     * @param mixed $newValue
     * @return mixed
     */
    protected function setDeepValue(mixed $offset, mixed $oldValue, mixed $newValue): mixed {
        $key = array_shift($offset);
        if (count($offset) === 0) {
            $oldValue[$key] = $newValue;
            return $oldValue;
        }

        if (empty($oldValue[$key])) $oldValue[$key] = [];
        $oldValue[$key] = $this->setDeepValue($offset ?: [], $oldValue[$key], $newValue);
        return $oldValue;
    }

}